package com.yuanxiao.common.core.result;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.yuanxiao.common.core.exception.RRException;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 返回数据（不再继承 HashMap）
 */
@JsonInclude(JsonInclude.Include.NON_NULL) // 可选：过滤 null 字段
public class R<T> implements Serializable {
	private static final long serialVersionUID = 1L;

	// 使用显式字段
	private String code;
	private String message;
	private T data;

	// 用于兼容旧的 put/get 方法
	private Map<String, Object> extra = new HashMap<>();

	public R() {
		this.code = ResultCode.SUCCESS.getCode();
		this.message = "success";
	}

	// ========== 兼容 HashMap put 方法 ==========
	public R<T> put(String key, Object value) {
		switch (key) {
			case "code":
				this.code = (String) value;
				break;
			case "message":
				this.message = (String) value;
				break;
			case "data":
				this.data = (T) value;
				break;
			default:
				extra.put(key, value);
		}
		return this;
	}

	// ========== 兼容 HashMap get 方法 ==========
	@SuppressWarnings("unchecked")
	public <V> V get(String key) {
		switch (key) {
			case "code":
				return (V) code;
			case "message":
				return (V) message;
			case "data":
				return (V) data;
			default:
				return (V) extra.get(key);
		}
	}

	// 核心方法：Jackson 会将这个 Map 中的内容作为额外字段输出到 JSON 顶层
	@JsonAnyGetter
	public Map<String, Object> getExtra() {
		return extra;
	}

	// 支持反序列化时动态字段回写
	@JsonAnySetter
	public void setExtra(String key, Object value) {
		extra.put(key, value);
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String msg) {
		this.message = msg;
	}

	// 保留原有方法，用于兼容历史版本
	public String getMsg() {
		return this.get("message").toString();
	}

	public T getData() {
		return data;
	}

	public R<T> setData(T data) {
		this.data = data;
		return this;
	}

	public static R<?> error() {
		return error(ResultCode.FAIL.getCode(), "未知异常");
	}

	public static R<?> error(String msg) {
		return error(ResultCode.FAIL.getCode(), msg);
	}

	public static R<?> error(String code, String msg) {
		R<Object> r = new R<>();
		r.setMessage (msg);
		r.setCode (code);
		return r;
	}

	public static R<?> ok(String msg) {
		R<Object> r = new R<>();
		r.setMessage (msg);
		return r;
	}

	public static <T> R<T> ok() {
		return new R<>();
	}

	public static <T> R<T> ok(T data) {
		R<T> r = new R<>();
		r.setMessage("success");
		r.setData(data);
		return r;
	}

	public static <T> R<T> failed(IResultCode resultCode) {
		R<T> r = new R<>();
		r.setCode (resultCode.getCode());
		r.setMessage (resultCode.getMsg());
		return r;
	}

	public static <T> R<T> failed(IResultCode resultCode, String msg) {
		R<T> r = new R<>();
		r.setCode (resultCode.getCode());
		r.setMessage (msg);
		return r;
	}

	public static <T> R<T> failed(String msg) {
		R<T> r = new R<>();
		r.setCode (ResultCode.SYSTEM_EXECUTION_ERROR.getCode());
		r.setMessage (msg);
		return r;
	}

	private static <T> R<T> returnWrapper(String code, String msg, Object... obj) {
		R<T> r = new R<>();
		r.setCode (code);
		r.setMessage (msg);
		if (obj != null && obj.length > 0) {
			Object first = obj[0];
			if (obj.length == 1) {
				r.setData((T) first); // 显式设置 data 字段
			} else {
				r.setData((T) obj); // 注意：如果 T 不是 Object[] 或 List，可能出错
			}
		} else {
			r.setData(null);
		}
		return r;
	}


	public static <T> R<T> returnDataWrapper(Object... obj) {
		return returnSuccessWrapper(obj);
	}

	public static <T> R<T> returnBoolWrapper(boolean bool, String fails, Object... obj) {
		return bool ? returnSuccessWrapper(obj) : returnFailsWrapper(fails, obj);
	}

	public static <T> R<T> returnSuccessWrapper(Object... obj) {
		return returnWrapper(ResultCode.SUCCESS.getCode(), "success", obj);
	}

	public static <T> R<T> returnFailsWrapper(String message, Object... obj) {
		return returnWrapper(ResultCode.FAIL.getCode(), message, obj);
	}

	public static boolean isSuccess(R<?> r) {
		return ResultCode.SUCCESS.getCode().equals(r.get("code").toString());
	}

	public static R<?> judge(boolean status) {
		return status ? ok() : error();
	}

	public static void throwMsg(boolean bool, String msg) {
		if (!bool) {
			throw new RRException(msg);
		}
	}

	public static void throwR(R<?> r) {
		if (!isSuccess(r)) {
			throw new RRException(r.getMessage ());
		}
	}

	/**
	 * 将任意 Object 数据转换为 List<T>
	 */
	public static <T> List<T> convertToList(Object data, Class<T> clazz) {
		if (data == null) {
			return null;
		}
		JSONArray jsonArray = JSONUtil.parseArray(data);
		return JSONUtil.toList(jsonArray, clazz);
	}

	/**
	 * 将任意 Object 数据转换为 T
	 */
	public static <T> T convertToBean(Object data, Class<T> clazz) {
		if (data == null) {
			return null;
		}
		String jsonStr = JSONUtil.toJsonStr(data);
		return JSONUtil.toBean(jsonStr, clazz);
	}

	/**
	 * 将任意 Object 数据转换为 HashMap
	 */
	public static HashMap convertToMap(Object data, Class<?> clazz) {
		if (data == null) {
			return null;
		}
		String jsonStr = JSONUtil.toJsonStr(data);
		return JSONUtil.toBean(jsonStr, HashMap.class);
	}
}
